﻿

#region File Description

#endregion


#region Using Statements

// System References
using System;
using System.Collections.Generic;
using System.Linq;

// XNA References
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

// Freeform References
using Freeform.Framework;
using Freeform.Framework.Graphics;
using Freeform.Framework.Utility;
using Freeform.Framework.Input;
using Freeform.Framework.Menu;
using System.Xml.Serialization;
using System.IO;

// Internal References

#endregion


namespace CardGame.Adventure
{
    public class TileClass : Entity
    {

        #region Members
        public Int32 TileWidth { get; set; }
        public Int32 TileHeight { get; set; }
        Texture2D Art;
        Texture2D IsoArt;
        Texture2D ArtRamp;
        public string ArtFileName { get; set; }
        public string FileName { get; set; }
        public Int32 MapWidth { get; set; }
        public Int32 MapHeight { get; set; }
        Single MapAngle;
        public Vector4[][] MapGrid { get; set; }
        Color HeightColor;
        Color LeftWallColor;
        Color RightWallColor;
        Single TileDepth;
        SpriteFont Debug;
        public bool IntiateLoadingProcedure = false;
        public bool IsVisible = true;

        //DOODADS NEED TO BE IMPLEMENTED
        //THEY WILL BE SORTED FOR CORRECT DEPTH SORTING
        //REGULAR TILES WILL NOT BE.
        #endregion


        #region Initialisation

        public TileClass(World W)
           : base(W)
        {
            Random r = new Random();
            TileWidth = 64;
            TileHeight = 64;
            MapWidth = 53;
            MapHeight = 53;
            MapGrid = new Vector4[MapHeight][];
            for(int i= 0; i < MapHeight; i++)
                MapGrid[i] = new Vector4[MapWidth];
            for (int i = 0; i < MapHeight; i++)
                for (int a = 0; a < MapWidth; a++)
                    MapGrid[i][a] = Vector4.One;

            Art = Game.Content.Load<Texture2D>("Texture/Adventure/Art/tempArtthree");
            ArtRamp = Game.Content.Load<Texture2D>("Texture/Adventure/Art/tempArtRamp");
            IsoArt = Game.Content.Load<Texture2D>("Texture/Adventure/Art/ttwall");
            MapAngle = 0.78f;
            TileDepth = 0.5f;
            Debug = Game.Content.Load<SpriteFont>("Font/Basic");

            LeftWallColor = new Color(150, 100, 150);
            RightWallColor = new Color(255, 50, 50);
            FileName = "hichris";
        }

        #endregion

        #region Draw

        /// <summary>
        /// Draws the entity onto the viewport.
        /// </summary>
        /// <param name="spatial">The spatial properties of the actor in world coordinates.</param>
        /// <param name="viewport">The viewport onto which the entity is being rendered.</param>
        /// <param name="time">Provides a snapshot of timing values.</param>

        protected override void DoDraw(GameTime Time, Viewport2D Viewport)
        {
            // Check early breaks.
            if (Viewport.SpriteBatch == null) return;
            if (this == null) return;
            if (!IsVisible) return;

            // Calculate drawing data.
            Vector2 Draw_Position = Viewport.Camera.TransformPosition(SpatialProperties.Position);
            Vector2 Draw_Size = new Vector2(TileWidth, TileHeight);
            Rectangle Draw_Source = new Rectangle(12, 12, 64, 64);

            //Draw entity.
            TileDepth = 0.5f;
            Single WallDepth = 0.5f;
            for (int CurrentHeightLayer = 0; CurrentHeightLayer <= 9; CurrentHeightLayer++)
            {
                WallDepth = TileDepth;
                for (int i = 0; i < MapHeight; i++)
                {
                    for (int a = 0; a < MapWidth; a++)
                    {
                        float Height = MapGrid[i][a].Y;
                        HeightColor = Color.LightBlue;
                        int TexIndex = (int)MapGrid[i][a].X;
                        TileDepth += .00001f;
                        WallDepth += 0.000001f;
                        if (Height + 0.5f == CurrentHeightLayer)
                        {
                            float TempDepth = WallDepth + 0.00001f;
                            LeftWallColor = new Color(90 + (40 * CurrentHeightLayer), 50, 150);
                            Draw_Source = new Rectangle(0, 0, 32, 47);
                            Draw_Size = new Vector2(32, 47);
                            MapAngle = 0f;
                            Rectangle Draw_LeftWall = new Rectangle(
                                (int)Draw_Position.X + ((a * TileWidth / 2) - (i * TileWidth / 2)), (int)Draw_Position.Y + ((i * TileHeight / 4) + (a * TileHeight / 4)) - (CurrentHeightLayer * TileHeight / 2) + (49),
                                (int)Draw_Size.X, (int)Draw_Size.Y);
                            Viewport.SpriteBatch.Draw(IsoArt, Draw_LeftWall, Draw_Source, LeftWallColor, MapAngle, Vector2.Zero, SpriteEffects.FlipHorizontally, WallDepth);

                            Draw_Size = new Vector2(TileWidth, TileHeight);
                            Draw_Source = new Rectangle(0, 0, 64, 64);
                            HeightColor = new Color(HeightColor.R - (30 * CurrentHeightLayer), HeightColor.G - (30 * CurrentHeightLayer), HeightColor.B - (30 * CurrentHeightLayer));
                            MapAngle = 0f;
                            Rectangle Draw_DestinationHeight = new Rectangle(
                                (int)Draw_Position.X + ((a * TileWidth / 2) - (i * TileWidth / 2)), (int)Draw_Position.Y + ((i * TileHeight / 4) + (a * TileHeight / 4)) - ((CurrentHeightLayer - 1) * TileHeight / 2),
                                (int)Draw_Size.X, (int)Draw_Size.Y);
                            Viewport.SpriteBatch.Draw(ArtRamp, Draw_DestinationHeight, Draw_Source, HeightColor, MapAngle, Vector2.Zero, SpriteEffects.None, TempDepth);

                            WallDepth += 0.00001f;
                        }
                        if (Height == CurrentHeightLayer)
                        {
                                    Draw_Size = new Vector2(TileWidth, TileHeight);
                                    Draw_Source = new Rectangle((64 * TexIndex), 0, 64, 64);
                                    HeightColor = new Color(HeightColor.R - (30 * CurrentHeightLayer), HeightColor.G - (30 * CurrentHeightLayer), HeightColor.B - (30 * CurrentHeightLayer));
                                    MapAngle = 0f;
                                    Rectangle Draw_DestinationHeight = new Rectangle(
                                        (int)Draw_Position.X + ((a * TileWidth / 2) - (i * TileWidth / 2)), (int)Draw_Position.Y + ((i * TileHeight / 4) + (a * TileHeight / 4)) - (CurrentHeightLayer * TileHeight / 2),
                                        (int)Draw_Size.X, (int)Draw_Size.Y);
                                    Viewport.SpriteBatch.Draw(Art, Draw_DestinationHeight, Draw_Source, HeightColor, MapAngle, Vector2.Zero, SpriteEffects.None, TileDepth);

                        }
                        if (Height >= CurrentHeightLayer && CurrentHeightLayer != 0)
                        {
                            LeftWallColor = new Color(90 + (40 * CurrentHeightLayer), 50, 150);
                            RightWallColor = new Color(60 + (40 * CurrentHeightLayer), 50, 90);
                            Draw_Source = new Rectangle(0, 0, 32, 47);
                            Draw_Size = new Vector2(32, 47);
                            MapAngle = 0f;
                            Rectangle Draw_LeftWall = new Rectangle(
                                (int)Draw_Position.X + ((a * TileWidth / 2) - (i * TileWidth / 2)), (int)Draw_Position.Y + ((i * TileHeight / 4) + (a * TileHeight / 4)) - (CurrentHeightLayer * TileHeight / 2) + (49),
                                (int)Draw_Size.X, (int)Draw_Size.Y);
                            Viewport.SpriteBatch.Draw(IsoArt, Draw_LeftWall, Draw_Source, LeftWallColor, MapAngle, Vector2.Zero, SpriteEffects.FlipHorizontally, WallDepth);

                            Rectangle Draw_RightWall = new Rectangle(
                               (int)Draw_Position.X + ((a * TileWidth / 2) - (i * TileWidth / 2)) + 32, (int)Draw_Position.Y + ((i * TileHeight / 4) + (a * TileHeight / 4)) - (CurrentHeightLayer * TileHeight / 2) + 49,
                               (int)Draw_Size.X, (int)Draw_Size.Y);
                            Viewport.SpriteBatch.Draw(IsoArt, Draw_RightWall, Draw_Source, RightWallColor, MapAngle, Vector2.Zero, SpriteEffects.None, WallDepth);


                        }
                    }
                }
            }
            // Draw entity.

        }

        #endregion


        protected override void DoUpdate(GameTime Time)
        {

            // TODO: Level selection subroutine to generate correct level filename.

            if (IntiateLoadingProcedure)
            {
                LoadMap("Content/" + FileName + ".xml");
                if (ArtFileName == "" || ArtFileName == null)
                    ArtFileName = "tempArtthree";

                DirectoryInfo Dir = new DirectoryInfo(Game.Content.RootDirectory + "/Texture/Adventure/Art/");
                if (!Dir.Exists)
                    throw new DirectoryNotFoundException();

                FileInfo[] Files = Dir.GetFiles("*.*");
                foreach (FileInfo F in Files)
                {
                    string literal = Path.GetFileNameWithoutExtension(F.Name);
                    if (literal == ArtFileName)
                    {
                        if (F.Extension == ".xnb")
                        {
                            Art = Game.Content.Load<Texture2D>("Texture/Adventure/Art/" + ArtFileName);
                            break;
                        }
                        else if (F.Extension == ".png")
                        {
                            Stream stream = File.OpenRead("Texture/Adventure/Art/" + ArtFileName + ".png");
                            Art = Texture2D.FromStream(Game.GraphicsDevice, stream);
                            stream.Close();
                            break;
                        }
                    }
                }
                IntiateLoadingProcedure = false;
            }
            base.DoUpdate(Time);
        }

        #region Utility

        public TileClass LoadMap(string filename)
        {
            TileClass Existing = this;
            Editor.EditorProtoClass Proto = new Editor.EditorProtoClass();
            XmlSerializer xml = new XmlSerializer(typeof(Editor.EditorProtoClass));
            Stream xmlReader = new FileStream(filename, FileMode.Open);

            Proto = (Editor.EditorProtoClass)xml.Deserialize(xmlReader);

            Existing = Editor.ConversionClass.ToAdventureClass(Proto, Existing);

            xmlReader.Close();

            //TODO: Load textures and un-serializable content.

            return Existing;
        }

        #endregion
    }
}
